package com.idp.saml;

import com.idp.metadata.MetadataBean;
import com.idp.metadata.MetadataConstants;
import org.apache.velocity.app.VelocityEngine;
import org.opensaml.common.SAMLObject;
import org.opensaml.common.binding.BasicSAMLMessageContext;
import org.opensaml.saml2.binding.encoding.HTTPPostSimpleSignEncoder;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.metadata.SingleSignOnService;
import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
import org.opensaml.xml.security.credential.Credential;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class SAMLResponseResolution {
    private static final Logger logger = LoggerFactory.getLogger(SAMLResponseResolution.class);
    private static final MetadataBean idpMetadata = SAMLResponse.getIdpMetadata();

    //remain
    public void send(AuthnRequest authnRequest, HttpServletResponse httpServletResponse, HttpServletRequest request, Response response) {
        VelocityEngine velocityEngine = new VelocityEngine();
        velocityEngine.setProperty("ISO-8859-1", "UTF-8");
        velocityEngine.setProperty("output.encoding", "UTF-8");
        velocityEngine.setProperty("resource.loader", "classpath");
        velocityEngine.setProperty("classpath.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        velocityEngine.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogChute");
        velocityEngine.init();
        HTTPPostSimpleSignEncoder httpPostSimpleSignEncoder = new HTTPPostSimpleSignEncoder(velocityEngine,
                "/templates/saml2-post-simplesign-binding.vm", false);
        HttpServletResponseAdapter outTransport = new HttpServletResponseAdapter(httpServletResponse, false);
        BasicSAMLMessageContext<?, Response, ?> messageContext = new BasicSAMLMessageContext<SAMLObject, Response, SAMLObject>();
        messageContext.setOutboundMessageTransport(outTransport);
        messageContext.setOutboundSAMLMessage(response);
        messageContext.setOutboundMessageIssuer(idpMetadata.getEntityId());
        SingleSignOnService endpoint = SAMLResponse.buildSAMLObject(SingleSignOnService.class);
        endpoint.setLocation(authnRequest.getAssertionConsumerServiceURL());
        endpoint.setBinding(MetadataConstants.HTTP_POST_BINDING);
        messageContext.setPeerEntityEndpoint(endpoint);
        messageContext.setRelayState(request.getParameter(AuthnRequestParameterConst.RELAY_STATE));
        try {
            httpPostSimpleSignEncoder.encode(messageContext);
        } catch (Exception e) {
            logger.error("encode error" + e.getMessage());
        }
    }

    //remain
    public void signAssertion(Response response) {
        Assertion assertion = response.getAssertions().get(0);
        Credential credential = idpMetadata.getSigningCredList().get(0);
        SignatureMethod.signObject(assertion, credential);
    }

    //remain
    public Response createSamlResponse(AuthnRequest authnRequest, MetadataBean spMetadata, Map<String, String> responseAssertMap) {
        // 里面有添加属性的方法
        Assertion assertion = SAMLResponse.buildAssertion(authnRequest, spMetadata, responseAssertMap);
        return SAMLResponse.buildResponse(authnRequest, assertion);
    }
}
